package com.xuexiang.xuidemo.page.uilts.component;

import ohos.aafwk.content.Intent;
import ohos.agp.animation.Animator;
import ohos.agp.components.Component;

import com.xuexiang.xui_lib.util.DisplayUtils;
import com.xuexiang.xui_lib.util.OfAnimatorProperty;
import com.xuexiang.xui_lib.util.OfAnimatorValue;
import com.xuexiang.xui_lib.util.StateChangedListenerAdapter;
import com.xuexiang.xuidemo.ResourceTable;
import com.xuexiang.xuidemo.page.base.BasePageAbilitySlice;
import com.xuexiang.xuidemo.page.base.Page;

/**
 * 属性动画
 *
 * @since 2021-03-25
 */
@Page(name = "属性动画", action = "utils.AnimationAbilitySlice")
public class AnimationAbilitySlice extends BasePageAbilitySlice implements Component.ClickedListener {
    private static final int DURATION_3000 = 3000;
    private static final int DURATION_1000 = 1000;
    private static final int INT_200 = 200;
    private static final int INT_360 = 360;
    private static final int INT_2 = 2;
    private static final float FLOAT_2 = 2F;
    private Component target;

    @Override
    protected int getLayoutId() {
        return ResourceTable.Layout_ability_utils_animation;
    }

    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
        target = findComponentById(ResourceTable.Id_target);
        findComponentById(ResourceTable.Id_anim_alpha).setClickedListener(this);
        findComponentById(ResourceTable.Id_anim_translation).setClickedListener(this);
        findComponentById(ResourceTable.Id_anim_zoom).setClickedListener(this);
        findComponentById(ResourceTable.Id_anim_rotate).setClickedListener(this);
        findComponentById(ResourceTable.Id_anim_value).setClickedListener(this);
        findComponentById(ResourceTable.Id_anim_evaluator).setClickedListener(this);
        findComponentById(ResourceTable.Id_anim_together1).setClickedListener(this);
        findComponentById(ResourceTable.Id_anim_together2).setClickedListener(this);
    }

    @Override
    public void onClick(Component component) {
        switch (component.getId()) {
            case ResourceTable.Id_anim_alpha:
                doAlphaAnimation(target);
                break;
            case ResourceTable.Id_anim_translation:
                doTranslationAnimation(target);
                break;
            case ResourceTable.Id_anim_zoom:
                doScaleAnimation(target);
                break;
            case ResourceTable.Id_anim_rotate:
                doRotationAnimation(target);
                break;
            case ResourceTable.Id_anim_value:
                doValueAnimator(target);
                break;
            case ResourceTable.Id_anim_evaluator:
                doTypeEvaluator(target);
                break;
            case ResourceTable.Id_anim_together1:
                doComposeAnimation1(target);
                break;
            case ResourceTable.Id_anim_together2:
                doComposeAnimation2(target);
                break;
            default:
                // NONE
        }
    }

    /**
     * 组合动画2
     *
     * @param component 目标动画
     */
    private void doComposeAnimation2(Component component) {
        long duration = DURATION_3000;
        new OfAnimatorProperty(component)
            .setDuration(duration)
            .alpha(1, 0.1F, 1)
            .start();
        new OfAnimatorProperty(component)
            .setDuration(duration)
            .scale(1F, 2F, 0.5F, 1F)
            .start();
        new OfAnimatorProperty(component)
            .setDuration(duration)
            .rotate(360, 720, 1080, 1440)
            .start();
    }

    /**
     * 组合动画
     *
     * @param component 目标动画
     */
    private void doComposeAnimation1(Component component) {
        long duration = DURATION_3000;
        new OfAnimatorProperty(component)
            .setDuration(duration)
            .alpha(1, 0, 1)
            .start();
        new OfAnimatorProperty(component)
            .setDuration(duration)
            .scale(1F, 0F, 1F)
            .start();
        new OfAnimatorProperty(component)
            .setDuration(duration)
            .rotate(INT_360, 0)
            .start();
    }

    /**
     * 插值器
     *
     * @param component 目标动画
     */
    private void doTypeEvaluator(Component component) {
        OfAnimatorValue setTo = new OfAnimatorValue()
            .ofValue(0, DisplayUtils.getDisplayWidthInPx(getContext()) / FLOAT_2)
            .duration(DURATION_3000);
        setTo.setCurveType(Animator.CurveType.OVERSHOOT);
        setTo.setValueUpdateListener((animatorValue, value) -> {
            component.setTranslation(value / INT_2, value);
        });
        setTo.setStateChangedListener(new StateChangedListenerAdapter() {
            @Override
            public void onEnd(Animator animator) {
                component.setTranslation(0, 0);
            }
        });
        setTo.start();
    }

    /**
     * 数值动画
     *
     * @param component 目标动画
     */
    private void doValueAnimator(Component component) {
        OfAnimatorValue setTo = new OfAnimatorValue()
            .ofValue(1, 0)
            .duration(DURATION_1000);
        setTo.setValueUpdateListener((animatorValue, value) -> {
            component.setScaleX(value);
            component.setScaleY(value);
            component.setAlpha(value);
            component.setRotation(INT_360 * (1 - value));
        });
        OfAnimatorValue reSet = new OfAnimatorValue()
            .ofValue(0, 1)
            .duration(DURATION_1000);
        reSet.setValueUpdateListener((animatorValue, value) -> {
            component.setScaleX(value);
            component.setScaleY(value);
            component.setAlpha(value);
            component.setRotation(INT_360 * (1 - value));
        });

        setTo.setStateChangedListener(new StateChangedListenerAdapter() {
            @Override
            public void onEnd(Animator animator) {
                reSet.start();
            }
        });
        setTo.start();
    }

    /**
     * 旋转动画
     *
     * @param component 目标动画
     */
    private void doRotationAnimation(Component component) {
        new OfAnimatorProperty(component)
            .rotate(0, INT_360, 0)
            .setDuration(DURATION_3000)
            .start();
    }

    /**
     * 缩放动画
     *
     * @param component 目标动画
     */
    private void doScaleAnimation(Component component) {
        new OfAnimatorProperty(component)
            .scale(1F, 0.5F, 1F, 1.5F, 1F)
            .setDuration(DURATION_3000)
            .start();
    }

    /**
     * 平移动画
     *
     * @param component 目标动画
     */
    private void doTranslationAnimation(Component component) {
        int startX = (DisplayUtils.getDisplayWidthInPx(getContext()) - component.getWidth()) / INT_2;
        int startY = (DisplayUtils.getDisplayHeightInPx(getContext()) - component.getHeight()) / INT_2;
        int move = INT_200;
        int maxMoveX = startX + move;
        int minMoveX = startX - move;
        int maxMoveY = startY + move;
        int minMoveY = startY - move;

        new OfAnimatorProperty(component)
            .moveX(startX, maxMoveX, startX, minMoveX, startX)
            .moveY(startY, maxMoveY, startY, minMoveY, startY)
            .setDuration(DURATION_3000)
            .start();
    }

    /**
     * 透明度动画
     *
     * @param component 目标动画
     */
    private void doAlphaAnimation(Component component) {
        new OfAnimatorProperty(component)
            .alpha(1, 0, 1)
            .setDuration(DURATION_3000)
            .start();
    }
}
